题目要求——
象棋棋盘上以A代表将,B代表帅,将帅不能相对,请输出所有合理的位置。A,B均可以以数字1到9的九宫格来显示。另外要求,只能用一个变量。
A ——
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
B——
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
解题思路——
依次遍历A 、B的位置,只要A、B分别对3取模而不相等,则是合理的位置,输出。
如果没有最后一个限制条件,这非常简单——
int num =0;
longtime = System.currentTimeMillis();
for(int j = 1; j < 10; j++) {
for(int j2 = 1; j2 <10; j2++) {
if((j%3)!=(j2%3)){
System.out.print("A="+j+",B="+j2+" ");
num++;
}
if(num%6 == 0) {
System.out.println();
}
}
}
System.out.println("共有"+num+"个,时间是:"+(System.currentTimeMillis()-time)+"毫秒");
运行时间是—— 2ms
然而,最后一个限制条件,要求只能用一个变量,就必须用位运算了。
由于java的byte的范围是-128到+127,不怎么好处理,因此这里用int的低8位,高4位和低4位分别代表两个循环的变量。
public static void main(String args[]){
int num = 0;
int i= 0x99;
for (; (i&0x0F)>0; i--) {
for (; ((i>>4)&0x0f)>0; i-=16) {
if ((i&0x0F)%3 != ((i>>4)&0x0f)%3 ) {
System.out.print("A="+(i&0x0F)+",B="+((i>>4)&0x0f)+" ");
num++;
}
if (num%6 == 0) {
System.out.println();
}
if (((i>>4)&0x0f) == 1) {
i &= 0x0f;
i += 0x90;
break;
}
}
}
System.out.println("共有"+num+"个");
}
运行结果——
看了《编程之美》上介绍的一种解法,甚为精妙,
byte i = 81;
while(i--){
if (i/9 %3 == i %9 % 3) {
continue;
}
System.out.print("A="+(i/9+1)+",B="+(i%9+1)+" ");
}
这种解法我想应该是由解法1(即用两个变量)归纳所得的,因为找出了两个变量之间的关系,因此就可以用一个变量来表示两个变量了。
这道题让我想起来了今年烽火通信实习生笔试的一个简单的考题,用来考考小学弟小学妹最好玩了。
题目是
不利用第三变量交换两个变量的值,假如是int型。
不难,用加减法就行。
a = a+b;
b = a-b;
a = a-b;
但是有些人一开始想到的居然是乘除。乘除的缺点是比加减更容易溢出,而且0不能作为除数,所以需要多加几句边界调节限定。
读后感——因为有了最后一个限制条件,所以这道题具有挑战性,